/*****************************************************************************
*
*  @file     FlashDriver.h
*  @brief    Flash驱动
*            1. 负责实现Flash驱动
*			 2. 提供数据存储和读取接口
*
*  @author   潘学林
*  @email                                        
*  @version  V0.000
*  @date     2022/4/13
*  @license  /
*----------------------------------------------------------------------------*
*  Remark         : Description                                              *
*----------------------------------------------------------------------------*
*  Change History :                                                          *
*  <Date>     | <Version> | <Author>       | <Description>                   *
*----------------------------------------------------------------------------*
*  2022/4/13  | 0.000     | 潘学林         | 创建文件                        *
*----------------------------------------------------------------------------*
*
*****************************************************************************/

#ifndef _FLASHDRIVER_H_
#define _FLASHDRIVER_H_

/* Includes ------------------------------------------------------------------*/

#include "Std_Types.h" 
#include "gd32f30x.h"
#include "systick.h"

/* Micros/Enumerate/Structures -----------------------------------------------*/

/* BANK0一页大小为2K */
#define FMC_PAGE_SIZE           ((uint16_t)0x800U)
/* 起始地址 */
#define FMC_WRITE_START_ADDR    ((uint32_t)0x0807F000U)
/* 结束地址 */
#define FMC_WRITE_END_ADDR      ((uint32_t)0x0807F800U)

/* 计算页数 */
#define PAGE_NUM ((FMC_WRITE_END_ADDR - FMC_WRITE_START_ADDR) / FMC_PAGE_SIZE)
/* 一页的数据长度（u32） */
#define ONE_PAGE_WORD_NUM (FMC_PAGE_SIZE >> 2)

/* 结构体成员偏移地址 */
#define STRUCT_MEMBER_OFFSET_ADDR(structType,member) ((int)&(((structType*)0)->member))

/**
 * @brief 第一次运行标识
 */
/* 系统第一次运行标识码 */
#define FIRST_RUN_CODE 0xA5A55A5A
/* 系统第一次运行标识对比确认 */
#define IS_FIRST_RUN(f) (f == FIRST_RUN_CODE)

/* FLASH擦除超时时间，单位：ms */
#define FLASH_ERASE_TIMEOUT 1000

/* FLASH存储数据长度，实际使用的长度不能超过此长度，单位：uint32 也就是实际长度为 64*4=256B */
#define FLASH_STORE_DATA_LENGTH 64
/* 默认存储全FF */
#define FLASH_STORE_DEFAULT_VALUE 0xFFFFFFFF

/* 
*	是否是第一次运行
* 定义表示每次都是第一次运行
* 未定义表示按照正常逻辑判断是是否是第一次运行
*/
/* #define IF_FIRSTRUN_EVERY_TIME */ 

/* 
*	是否开启FLASH自测功能 
* 定义表示开启FLASH自测功能 
* 未定义表示不开启FLASH自测功能 
*/
/* #define IF_ENABLE_FLASH_SELF_TEST */

/**
 * @brief 写数据状态
 * @note  None
 */
typedef enum FLASH_DRIVER_WRITE_STATE
{
    FLASH_DRIVER_WRITE_STATE_IDLE = 0, /* 空闲 */
    FLASH_DRIVER_WRITE_STATE_ERASE = 1, /* 擦除 */
    FLASH_DRIVER_WRITE_STATE_WAIT = 2, /* 等待 */
    FLASH_DRIVER_WRITE_STATE_WRITE = 3, /* 写入 */
    FLASH_DRIVER_WRITE_STATE_END = 4, /* 结束 */
}FLASH_DRIVER_WRITE_STATE;

/**
 * @brief 存储数据
 */
typedef struct PARAMETER_STORE_DATA
{
    uint32 data[FLASH_STORE_DATA_LENGTH]; /* 存储缓冲区 */
}PARAMETER_STORE_DATA; /* 共256字节 */

/**
 * @brief 参数存储信息
 */
typedef struct PARAMETER_STORE_INFO
{
    PARAMETER_STORE_DATA writeDataInfo; /* 写信息 */
    BOOL storeFlag; /* 存储标志 */
    FLASH_DRIVER_WRITE_STATE writeState; /* 写数据状态 */
    uint8 maintain[2]; /* 预留 */ 
}PARAMETER_STORE_INFO; /* 共256+4字节 */

/* Functions -----------------------------------------------------------------*/

/*****************************************
* 接口函数
*****************************************/
/**
  * @brief  Flash驱动初始化
  * @param  None
  * @retval None
  */
void FlashDriver_Init(void);

/**
  * @brief  Flash轮询任务
  * @param  None
  * @retval None
  */
void FlashDriver_PollTask(void);

/**
  * @brief  写数据
  * @param  datPtr 数据指针，length 数据长度
  * @retval 写入结果，0：写入成功 1：写入失败
  */
uint8 FlashDriver_WriteData(uint8 *datPtr, uint16 length);

/**
  * @brief  读数据
  * @param  datPtr 数据指针，length 数据长度
  * @retval 读取结果，0：读取成功 1：读取失败
  */
uint8 FlashDriver_ReadData(uint8 *datPtr, uint16 length);

/**
  * @brief  存储自测
  * @param  None
  * @retval None
  */
BOOL FlashDriver_SelfTest(void);

#endif

/********************************* END OF FILE ********************************/

